/**
 * @author Jrainlau
 * @desc Canjs类
 * 
 * @class
 * 
 * 传入字符串形式的es5代码，可选的新增全局变量
 * 运行`.run()`方法即可输出运行结果
 * 
 * eg: new Canjs('console.log("Hello World!")').run()
 */

const { Parser } = require('acorn')
const NodeIterator = require('./iterator')
const Scope = require('./scope')
const { global } = require('./standard')
const MYJSON = require('./global/JSON')
class Canjs {
  constructor (code = '', extraDeclaration = {}) {
    this.code = code
    this.extraDeclaration = extraDeclaration
    this.ast = Parser.parse(code,{ecmaVersion:8})
    this.nodeIterator = null
    this.init()
  }

  init () {
    const globalScope = new Scope('function')
    Object.keys(this.extraDeclaration).forEach((key) => {
      globalScope.addDeclaration(key, this.extraDeclaration[key])
    })
    this.nodeIterator = new NodeIterator(null, globalScope)
  }

  run () {
    return this.nodeIterator.traverse(this.ast)
  }
}

const code =`
function Promise3(callback) {
  var self = this;
  self.status = 'PENDING'; // Promise3当前的状态
  self.data = undefined; // Promise3的值
  self.onResolvedCallback = []; // Promise3 resolve时的回调函数集
  self.onRejectedCallback = []; // Promise3 reject时的回调函数集
  callback(resolve, reject); // 执行executor并传入相应的参数

  function resolve(value) {
    if (self.status == 'PENDING') {
      self.status = 'FULFILLED';
      self.data = value;
      // 依次执行成功之后的函数栈
      for (var i = 0; i < self.onResolvedCallback.length; i++) {
        console.log(777)
        self.onResolvedCallback[i](value);
      }
      
    }
  }

  function reject(error) {
    if (self.status === 'PENDING') {
      self.status = 'REJECTED';
      self.data = error;
      // 依次执行失败之后的函数栈
      for (var i = 0; i < self.onRejectedCallback.length; i++) {
        self.onRejectedCallback[i](error);
      }
    }
  }
}

Promise3.prototype.then = function (onResolved, onRejected) {
  let self = this;
  // 根据标准，如果then的参数不是function，则我们需要忽略它，此处以如下方式处理
  onResolved = typeof onResolved === 'function' ? onResolved : function (value) { };
  onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { };
  
  if (self.status === 'FULFILLED') {
    
    // 如果Promise31(此处即为this/self)的状态已经确定并且是resolved，我们调用onResolved
    // 因为考虑到有可能throw，所以我们将其包在try/catch块里
    return new Promise3(function (resolve, reject) {
      
      onResolved(self.data)
    });
    
  }
}

// new Promise3(function(resolve, reject){
//   const asd = {
//     a:'aa',
//     bb:{
//       bb1:'bb1'
//     },
//     cc:[
//       1,2,'stgr'
//     ],
//     qq:[
//       {
//         type:'dengy',
//         name:'vanamm'
//       }
//     ],
//     xa:123
//   }
//   resolve(asd)
// }).then(function(data){
//   console.log(MYJSON.stringify(data))
// })

// class Tes{
//   constructor(tsa){
//     this.xx = tsa
//   }
//   xw(){
//     console.log(441)
//   }
// }
// const wha = new Tes('zjl')
// wha.xw();
// console.log(wha)
`;

new Canjs(code,{MYJSON}).run()


// class ts{
//   constructor(){

//   }

//   fnx(){}
// }

// const cc = new ts()
// console.log(cc);

// console.dir(fn.__proto__ === Function.prototype);

// const asd = {}
// console.dir(asd.__proto__ === Object.prototype);

// console.log(Function.__proto__ === Object.prototype);

// console.log(Object.__proto__ === Function.prototype);
